#include "Mutex.hpp"
#include <cstddef>
#include <pthread.h>
#include <unistd.h>
#include <mutex>
using namespace MutexModule;
using namespace std;
int ticket = 1000;
mutex cpp_lock;
class ThreadDate {
public:
    ThreadDate(const string& n, Mutex& lock)
    :name(n), lockp(lock) {}
    ~ThreadDate() {}
    string name;
    Mutex& lockp; // 这里可以是指针也可以是引用，但是不可以是值
};
void* route(void* args) {
    // 一种写法（线程库中的互斥量）
    // ThreadDate* td = static_cast<ThreadDate*>(args);
    // while (true) {
    //     LockGuard guard(td->lockp);
    //     if(ticket > 0) {
    //         usleep(1000);
    //         printf("%s, sells ticker:%d\n", td->name.c_str(), ticket);
    //         ticket--;
    //     }else {
    //         break;
    //     }
    // }
    // return nullptr;
    // ******************************************
    // 第二种写法（c++库里面的）
    ThreadDate* td = static_cast<ThreadDate*>(args);
    while (true) {
        cpp_lock.lock();
        if(ticket > 0) {
            usleep(1000);
            printf("%s, sells ticker:%d\n", td->name.c_str(), ticket);
            ticket--;
            cpp_lock.unlock();
        }else {
            cpp_lock.unlock();
            break;
        }
    }
    return nullptr;
}
int main() {
    Mutex lock;
    pthread_t t1, t2, t3, t4;
    ThreadDate* td1 = new ThreadDate("thread_1", lock);
    pthread_create(&t1, NULL, route, td1);
    ThreadDate* td2 = new ThreadDate("thread_2", lock);
    pthread_create(&t2, NULL, route, td2);
    ThreadDate* td3 = new ThreadDate("thread_3", lock);
    pthread_create(&t3, NULL, route, td3);
    ThreadDate* td4 = new ThreadDate("thread_4", lock);
    pthread_create(&t4, NULL, route, td4);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_join(t3, NULL);
    pthread_join(t4, NULL);
    return 0;
}